using System;
using System.Text;
using Sirenix.OdinInspector;
using Sirenix.Serialization;

namespace BTEditor
{
    [BTDecorator]
    public class Cooldown : Decorator
    {
        public override Type GetNodeType()
        {
            return typeof(NPBehave.Cooldown);
        }

        public override ErrorType GetIsVaild()
        {
            return BelongNode.IsHaveChild ? ErrorType.None : ErrorType.Error;
        }

        protected override void DealField(StringBuilder sb)
        {
            sb.Append($"{cooldownTime.ToArgs()},");
            if (argsCountType == ArgsCountType.Two)
            {
                sb.Append($"{randomVariation.ToArgs()},");
            }
            if (argsCountType == ArgsCountType.Three)
            {
                sb.Append($"{startAfterDecoratee.ToArgs()},");
                sb.Append($"{resetOnFailiure.ToArgs()},");
            }
            if (argsCountType == ArgsCountType.Four)
            {
                sb.Append($"{randomVariation.ToArgs()},");
                sb.Append($"{startAfterDecoratee.ToArgs()},");
                sb.Append($"{resetOnFailiure.ToArgs()},");
            }
        }
        
        public override int ShowArgsMask => (int) (ArgsCountType.Two | ArgsCountType.Three | ArgsCountType.Four | ArgsCountType.One);
        
        [InfoBox("Run decoratee immediately, but only if last execution wasn't at least past cooldownTime with randomVariation. When startAfterDecoratee is true, the cooldown timer will be started after the decoratee finishes instead of when it starts. When resetOnFailure is true, the cooldown will be reset if the decorated node fails.","infoBox")]
        [Title("是否显示节点注释")]
        [LabelText("显示节点注释 ： ")]
        public bool infoBox;

        [EnumButton("ShowArgsMask")]
        [HideLabel] 
        public ArgsCountType argsCountType;
        
        [OdinSerialize] [HideLabel] [Title("冷却时间")]
        public float cooldownTime = 0.0f;
        
        [HideLabel] [Title("是否在子节点结束后开始计算冷却时间")]   [OdinSerialize]
        [EnableIf("IsShow_startAfterDecoratee")]
        [InfoBox("When startAfterDecoratee is true, the cooldown timer will be started after the decoratee finishes instead of when it starts")]
        public bool startAfterDecoratee;
        
        [HideLabel] [Title("失败时是否重置")]   [OdinSerialize]
        [EnableIf("IsShow_startAfterDecoratee")]
        [InfoBox("When resetOnFailure is true, the cooldown will be reset if the decorated node fails.")]
        public bool resetOnFailiure = false;

        [HideLabel] [Title("时间差异")]   [OdinSerialize]
        [EnableIf("IsShow_randomVariation")]
        public float randomVariation = 0.05f;

        private bool IsShow_startAfterDecoratee()
        {
            return argsCountType == ArgsCountType.Three || argsCountType == ArgsCountType.Four;
        }

        private bool IsShow_randomVariation()
        {
            return argsCountType == ArgsCountType.Three || argsCountType == ArgsCountType.Two;
        }
    }
}